package com.fgi.springframework.context.support;

import com.fgi.springframework.beans.BeansException;
import com.fgi.springframework.beans.factory.ConfigurableListableBeanFactory;
import com.fgi.springframework.beans.factory.support.DefaultListableBeanFactory;

/**
 * Base class for {@link com.fgi.springframework.context.ApplicationContext}
 * implementations which are supposed to support multiple calls to {@link #refresh()},
 * creating a new internal bean factory instance every time.
 * Typically (but not necessarily), such a context will be driven by
 * a set of config locations to load bean definitions from.
 *
 * @author HanXu
 * @date 2022/11/24
 **/
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

    /**
     * 添加上层操作的 BeanFactory 属性, 进而实现 getBeanFactory 方法
     */
    private DefaultListableBeanFactory beanFactory;

    /**
     *  1. 创建 BeanFactory，并加载 BeanDefinition
     */
    @Override
    protected void refreshBeanFactory() throws BeansException {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    }

    private DefaultListableBeanFactory createBeanFactory() {
        // TODO 可能提供不同的工厂 ？？
        return new DefaultListableBeanFactory();
    }

    /**
     * 具体地加载工作由其子类实现，依赖XmlBeanDefinitionReader中的 loadBeanDefinitions 方法
     */
    protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory);

    /**
     * 2. 获取 BeanFactory
     */
    @Override
    protected ConfigurableListableBeanFactory getBeanFactory() {
        return beanFactory;
    }

}
